有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java停止线程和在哪里使用锁

我的问题是在哪里使用这些线程上的锁。当我让我的圈子相互竞争时,当一个人到达终点时,程序应该停止并宣布获胜。相反,它完成了所有的圆到终点线,我相信这是因为它们都共享相同的锁,甚至可能是资源

这是我的三门课。任何帮助都将不胜感激

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JButton;
import java.awt.GridLayout;

public class HorsePanel extends JFrame {

private JPanel panel;
private JButton reset;
private JButton quit;
private JButton run;
private ActionListener listener;
public static final int FRAME_WIDTH = 500;
public static final int FRAME_HEIGHT = 400;

private TrackPane trackPane;

public HorsePanel(TrackPane t) {
    trackPane = t;
    createPanel();
    createRunRace();
    createQuit();
    setSize(FRAME_WIDTH, FRAME_HEIGHT);
}

public void createRunRace() {

    class RunRace implements ActionListener {

        public void actionPerformed(ActionEvent rightEvent) {
            run.setEnabled(false);
            trackPane.start();

        }
    }

    ActionListener a = new RunRace();
    this.run.addActionListener(a);
}

public void createQuit() {
    class QuitRace implements ActionListener {

        public void actionPerformed(ActionEvent rightEvent) {
            System.exit(0);
        }
    }

    ActionListener b = new QuitRace();
    this.quit.addActionListener(b);
}


public void createReset() {
    class ResetRace implements ActionListener {

        public void actionPerformed(ActionEvent rightEvent) {
            //trackPane.resetCoordinates;
            run.setEnabled(true);
        }
    }

    ActionListener c = new ResetRace();
    this.reset.addActionListener(c);
}

public void createPanel() {
    panel = new JPanel(new BorderLayout());
    trackPane = new TrackPane();
    this.run = new JButton("Run Race");
    this.quit = new JButton("Quit");
    this.reset = new JButton("Reset");
    JPanel topPanel = new JPanel();

    topPanel.setLayout(new GridLayout(1, 3));
    topPanel.add(run);
    topPanel.add(reset);
    topPanel.add(quit);
    panel.add(topPanel, BorderLayout.NORTH);
    panel.add(trackPane, BorderLayout.CENTER);

    add(panel);
}
}




import javax.swing.JFrame;



public class HorseTester {
public static TrackPane t = new TrackPane();
public static void main(String[] args) {
    new HorseTester();
}

public HorseTester() {
    JFrame frame = new HorsePanel(t);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);
}
}

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import javax.swing.JFrame;
import javax.swing.JOptionPane;

public class HorseThread implements Runnable {

public static final int X_START = 10;
public static final int Y_START = 20;
private boolean RUNNING = true;
public int FINISH_LINE = 450;
private Horse horse;
private int xpos, ypos;
private TrackPane track;
public JFrame frame = new JFrame();
public int id;

public HorseThread(TrackPane track, int offset) {
    xpos = X_START;
    id = offset;
    // Spaces the horses apart
    ypos = Y_START * offset * 3;
    horse = new Horse(xpos, ypos);
    this.track = track;
}


public void paint(Graphics g) {
    Graphics2D g2 = (Graphics2D) g;
    horse.draw(g2);
}

/**
 * Run method that thread executes and makes horses go across the screen
 * racing.
 */
public void run() {

    while (RUNNING) {

            //varying the x position movement
            horse.setX(xpos += (int) (Math.random() * 10 + 1), id);
            // Sleeping the thread
            track.repaint();
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (xpos >= FINISH_LINE) {
                RUNNING = false;
            }


        }
    }
}




public class Horse {

private int xTop, xStart;
private int yTop, yStart;
public static final int RING_WIDTH = 20, FINISH_LINE=450;
public JFrame frame = new JFrame();
public Lock lockThing = new ReentrantLock();

public Horse(int x, int y) {
    xTop = x;
    yTop = y;
    xStart = x;
    yStart = y;
}



public void setX(int dx, int id) {
    try{
        lockThing.lock();
        xTop=dx;
        if (dx >= FINISH_LINE){
            JOptionPane.showMessageDialog(frame, id + " Won");
        }

    }finally{ lockThing.unlock();}
}

public void draw(Graphics2D g2) {
    Ellipse2D.Double horse = new Ellipse2D.Double(xTop, yTop, RING_WIDTH,
            RING_WIDTH);
    g2.setColor(Color.RED);
    g2.fill(horse);
    g2.setColor(Color.BLUE);
    g2.draw(horse);
}
}



public class TrackPane extends JPanel {

private static final int NUM_OF_HORSES = 5;

private ArrayList<HorseThread> horses = new ArrayList<HorseThread>();
private ArrayList<Thread> threads = new ArrayList<Thread>(25);

public TrackPane() {
    setBackground(Color.WHITE);
    reset();
}

public void reset() {
    // Should dispose of any running threads...
    horses.clear();
    // Allocating the memory for horses
    for (int i = 0; i < NUM_OF_HORSES; i++) {
        horses.add(new HorseThread(this, i + 1));
    }
}

public void start() {
    // Should dispose of any running threads...
    threads.clear();
    for (int i = 0; i < horses.size(); i++) {
        Thread thread = new Thread(horses.get(i));
        thread.start();
        threads.add(thread);
    }
}


@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);

    for (HorseThread horse : horses) {
        horse.paint(g);
    }
}

}

共 (1) 个答案

  1. # 1 楼答案

    您需要在线程之间共享运行变量

    private boolean RUNNING = true;
    

    最快的方法(但不是最好的方法)是将其更改为静态:

    private static volatile boolean RUNNING = true;
    

    更合适、更幸运的方法是创建一个组件,该组件将在线程之间共享,并负责同步。 另一个乱七八糟的是弹出窗口:

    JOptionPane.showMessageDialog(new JFrame(), id + " Won");
    

    这会阻止一个线程,直到有人关闭它们,这会阻止你的线程将RUNNING设置为false。 将此逻辑移动到运行HorseThread方法,并将其从Horse类的setX方法中删除:

    class HorseThread implements Runnable {
    
    private static volatile boolean RUNNING = true;
    public static final int X_START = 10;
    public static final int Y_START = 20;
    public int FINISH_LINE = 450;
    private Horse horse;
    private int xpos, ypos;
    private TrackPane track;
    public JFrame frame = new JFrame();
    public int id;
    
    public HorseThread(TrackPane track, int offset) {
        xpos = X_START;
        id = offset;
        // Spaces the horses apart
        ypos = Y_START * offset * 3;
        horse = new Horse(xpos, ypos);
        this.track = track;
    }
    
    
    public void paint(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
        horse.draw(g2);
    }
    
    /**
     * Run method that thread executes and makes horses go across the screen
     * racing.
     */
    public void run() {
    
        while (RUNNING) {
    
            //varying the x position movement
            horse.setX(xpos += (int) (Math.random() * 10 + 1), id);
            // Sleeping the thread
            track.repaint();
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (xpos >= FINISH_LINE) {
                RUNNING = false;
                JOptionPane.showMessageDialog(new JFrame(), id + " Won");
            }
    
    
        }
        }
    }
    
    
    
    class Horse {
    
    private int xTop, xStart;
    private int yTop, yStart;
    public static final int RING_WIDTH = 20, FINISH_LINE=450;
    public JFrame frame = new JFrame();
    public Lock lockThing = new ReentrantLock();
    
    public Horse(int x, int y) {
        xTop = x;
        yTop = y;
        xStart = x;
        yStart = y;
    }
    
    
    
    public void setX(int dx, int id) {
        try{
            lockThing.lock();
            xTop=dx;
    
        }finally{ lockThing.unlock();}
    }
    
    public void draw(Graphics2D g2) {
        Ellipse2D.Double horse = new Ellipse2D.Double(xTop, yTop, RING_WIDTH,
                RING_WIDTH);
        g2.setColor(Color.RED);
        g2.fill(horse);
        g2.setColor(Color.BLUE);
        g2.draw(horse);
        }
    }